using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Microsoft.Xna.Framework;

namespace ProjectCastamere
{
    class CameraPath
    {
        public struct KeyFrame
        {
            public Vector3 position;
            public Vector3 lookAt;
            public float frameNo;
        }

        private List<KeyFrame> keyFrames = new List<KeyFrame>();
        /// <summary>
        /// total time the animation takes
        /// </summary>
        private float totalTime = 0.0f;

        /// <summary>
        /// Loads the camera path from the map file
        /// </summary>
        /// <param name="file"></param>
        public CameraPath(DataTypes.MapFile file)
        {
            foreach(DataTypes.MapFile.CamKeyFrame frame in file.CameraKeyFrames)
            {
                KeyFrame f = new KeyFrame();
                f.position = frame.Position;
                f.lookAt = frame.LookAt;
                f.frameNo = frame.FrameNo;
                if (frame.FrameNo > totalTime)
                {
                    totalTime = frame.FrameNo;
                }
                keyFrames.Add(f);
            }

            // TODO: sort the keyFrames array by frameNo
            // (assumes the list is already ordered)
        }

        public float GetAnimationTime()
        {
            return totalTime;
        }

        public Matrix GetViewMatrix(float time)
        {
            if (keyFrames.Count < 1)
            {
                return Matrix.Identity;
            }

            // find the two key frames that the 'time' parameter lies between
            int index = 0;
            while (index < keyFrames.Count && time > keyFrames[index].frameNo)
            {
                index++;
            }
            index--;

            Vector3 pos, lookAt;
            // if it goes past the last frame
            if (index >= keyFrames.Count - 1)
            {
                pos = keyFrames.Last().position;
                lookAt = keyFrames.Last().lookAt;
            }
            else
            {
                float ratio = (time - keyFrames[index].frameNo) / (keyFrames[index + 1].frameNo - keyFrames[index].frameNo);

                pos = keyFrames[index].position + (keyFrames[index + 1].position - keyFrames[index].position) * ratio;
                lookAt = keyFrames[index].lookAt + (keyFrames[index + 1].lookAt - keyFrames[index].lookAt) * ratio;
            }

            return Matrix.CreateLookAt(pos, lookAt, Vector3.Up);
        }
    }
}
